﻿#include "DynaImages.h"

#include <QFileDialog>
#include <QDateTime>
#include <QMessageBox>
#include <QRgb>


//水平翻转
void horiFlip(QImage &image)
{
	image = image.mirrored(true, false);
}

//垂直翻转
void vertFlip(QImage &image)
{
	image = image.mirrored(false, true);
}

//旋转，顺时针为正
void rotate(QImage &image, double angle)
{
	QMatrix matrix;
	matrix.rotate(angle);
	image = image.transformed(matrix, Qt::FastTransformation);
}

DynaImages::DynaImages(QWidget *parent)
	: QMainWindow(parent)
	, m_dt(STANDARD_DT)
	, m_nTimerID(-1)
	, m_fRotateAngle(0)
	, m_bStart(false)
	, m_threshould(25)
{
	ui.setupUi(this);
	ui.index->setValue(0);
	ui.index->setTickInterval(1);

	for (int i = 0; i < MAXDIM; i++)
	{
		for (int j = 0; j < MAXDIM; j++)
		{
			m_gridGray[i][j] = 0;
		}
	}


}
void DynaImages::on_action_Open_triggered()
{
	on_stop_clicked();

	m_sDirPath = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
		"", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
	if (m_sDirPath.isEmpty()) return;

	QDir dir(m_sDirPath);
	m_FileList = dir.entryList(QDir::Files | QDir::Readable, QDir::Name);
	ui.index->setMaximum(m_FileList.size() - 1);
	ui.index->setValue(0);
	ui.index->setTickInterval(1);
	m_dt = STANDARD_DT;
	setWindowTitle("DynaImages v1.0 -- " + m_sDirPath);

	on_start_clicked();
}

void DynaImages::on_action_Close_triggered()
{
	if (m_nTimerID != -1)
	{
		killTimer(m_nTimerID);
		m_nTimerID = -1;
		ui.start->setText("Start");
	}
	m_FileList.clear();
	ui.index->setValue(0);
	ui.image->setPixmap(QPixmap(""));
}

void DynaImages::on_action_Faster_triggered()
{
	m_dt = int(m_dt*2.0/3.0);
	if (m_dt <= 0)
	{
		m_dt = 1;
		int interval = ui.index->tickInterval();
		interval = ceill(interval*1.5);
		ui.index->setTickInterval(interval);
	}
	if (m_nTimerID != -1)
	{
		killTimer(m_nTimerID);
		m_nTimerID = startTimer(m_dt);
	}
}

void DynaImages::on_action_Slower_triggered()
{
	int interval = ui.index->tickInterval();
	if (interval > 1)
	{
		interval = int(interval*2.0 / 3.0);
		if (interval < 1) interval = 1;
		ui.index->setTickInterval(interval);
	}
	else
		m_dt += int(m_dt*1.5);

	if (m_nTimerID != -1)
	{
		killTimer(m_nTimerID);
		m_nTimerID = startTimer(m_dt);
	}
}


void DynaImages::timerEvent(QTimerEvent *event)
{
	static bool bBusy = false;

	if (event->timerId() == m_nTimerID)
	{
		if (bBusy)
		{
			ui.index->setValue(ui.index->value() + ui.index->tickInterval());
			bBusy = false;
			return;
		}

		bBusy = true;

		if (ui.index->value() >= m_FileList.size())
		{
			killTimer(m_nTimerID);
			m_nTimerID = -1;
			bBusy = false;
			ui.start->setText("Start");
			return;
		}

		ui.index->setValue(ui.index->value() + ui.index->tickInterval());

		bBusy = false;
	}

}

void DynaImages::on_last_clicked()
{
	int value = ui.index->value() - 1;
	if (value < 0) return;
	ui.index->setValue(value);
}


void DynaImages::on_next_clicked()
{
	int value = ui.index->value() + 1;
	if (ui.index->value() >= m_FileList.size()) return;
	ui.index->setValue(value);
}



void DynaImages::on_start_clicked()
{
	if (!m_bStart)
	{
		if (m_FileList.size() == 0) return;
		if (m_nTimerID != -1) return;
		m_nTimerID = startTimer(m_dt);
		m_bStart = true;
		ui.start->setText("Pause");
	}
	else
	{
		killTimer(m_nTimerID);
		m_nTimerID = -1;
		m_bStart = false;
		ui.start->setText("Start");
	}
}

void DynaImages::on_faster_clicked()
{
	on_action_Faster_triggered();
}

void DynaImages::on_slower_clicked()
{
	on_action_Slower_triggered();
}

void DynaImages::on_stop_clicked()
{
	killTimer(m_nTimerID);
	m_nTimerID = -1;
	ui.start->setText("Start");
}

void DynaImages::on_rotate_clicked()
{
	m_fRotateAngle -= 90.0;
	refreshImage();
}

void DynaImages::on_index_valueChanged()
{
	refreshImage();
}

void DynaImages::refreshImage()
{
	int index = ui.index->value();
	if (index >= m_FileList.size()) return;

	QString name = m_FileList.at(index);
	QString filePath = m_sDirPath + "/" + name;
	m_img.load(filePath);
	int width = m_img.width();
	int height = m_img.height();
	if (m_fRotateAngle != 0)
		rotate(m_img, m_fRotateAngle);

	QImage img1 = m_img.scaled(ui.image->size(), Qt::KeepAspectRatio);
	ui.image->setPixmap(QPixmap::fromImage(img1));

	//HI_1590592829937.jpg
	int k1 = name.indexOf("_") +1;
	int k2 = name.lastIndexOf(".");
	QString str = name.mid(k1, k2 - k1);
	QDateTime tm = QDateTime::fromMSecsSinceEpoch(str.toLongLong());
	
	ui.fileInfo->setPlainText(QString("%1/%2    %3    %4    dt=%5    interval=%6")
		.arg(index)
		.arg(m_FileList.size())
		.arg(tm.toString("yyyy/MM/dd hh:mm:ss"))
		.arg(name)
		.arg(m_dt)
		.arg(ui.index->tickInterval()));

	displayImageInfo(m_img);
	
}


void DynaImages::displayImageInfo(const QImage &image)
{
	int width = image.width();
	int height = image.height();
	int totalPixels = width*height;

	
	int maxGray = 0;		//最大灰度
	int minGray = 255;		//最小灰度
	int averGray = 0;		//平均灰度
	int nBrightPixel = 0;	//超过阈值的像素数

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			QRgb rgb = image.pixel(j, i);
			int gray = qGray(rgb);
			averGray += gray;
			if (gray > m_threshould) nBrightPixel++;
			if (gray > maxGray) maxGray = gray;
			if (gray < minGray) minGray = gray;
		}
	}
	averGray = int((double)averGray / totalPixels);

	///////////////////////////////////////////////////////////////
	// 判断物体移动，采用网格分区采样灰度平均值
	int dynaValue = 0;						//动态表征值
	int width_grid = ceil(width / DIST);	//横向网格数
	int height_grid = ceil(height / DIST);	//横向网格数
	int total_grid = width_grid*height_grid;//总网格数
	int newGridGray[MAXDIM][MAXDIM];		//网格平均灰度

	//初始化网格数组
	for (int i = 0; i < height_grid; i++)
	{
		for (int j = 0; j < width_grid; j++)
		{
			newGridGray[i][j] = 0;
		}
	}

	//计算网格灰度累计值
	for (int i = 0; i < height; i++)
	{
		int row = i >> 6;
		for (int j = 0; j < width; j++)
		{
			QRgb rgb = image.pixel(j, i);
			int gray = qGray(rgb);
			int col = j >> 6;
			newGridGray[row][col] += gray;
		}
	}

	//计算网格灰度
	double block = 1.0 / (DIST*DIST);
	for (int i = 0; i < height_grid; i++)
	{
		for (int j = 0; j < width_grid; j++)
		{
			newGridGray[i][j] = int(newGridGray[i][j] * block); //如果右侧边缘和下部边缘分块较小，则等价于其权重较小，不影响差异计算
		}
	}

	//计算网格最大差异
	int max_diff = 0;
	int row = 0;	//最大差异出现的网格行位置
	int col = 0;	//最大差异出现的网格列位置
	for (int i = 0; i < height_grid; i++)
	{
		for (int j = 0; j < width_grid; j++)
		{
			int df = abs(newGridGray[i][j] - m_gridGray[i][j]);
			if (df > max_diff)
			{
				max_diff = df;
				row = i;
				col = j;
			}
		}
	}
	///////////////////////////////////////////////////////////////

	//更新区域灰度
	for (int i = 0; i < height_grid; i++)
	{
		for (int j = 0; j < width_grid; j++)
		{
			m_gridGray[i][j] = newGridGray[i][j];
		}
	}

	if (max_diff > 30)
	{
		ui.indicator->setStyleSheet("border-radius:12px;background-color: rgb(255, 0, 0);");
	}
	else
	{
		ui.indicator->setStyleSheet("border-radius:12px;background-color: rgb(0, 0, 0);");
	}

	ui.imageInfo->setPlainText(QString("AVER=%1  MAX=%2  MIN=%3  BRIGHT=%4%  MAX_DIFF=%5  ROW=%6  COL=%7")
		.arg(averGray)
		.arg(maxGray)
		.arg(minGray)
		.arg(int(100.0*nBrightPixel / totalPixels))
		.arg(max_diff)
		.arg(row)
		.arg(col)
	);
}


void DynaImages::on_action_Compare_triggered()
{
	QString fileName1 = QFileDialog::getOpenFileName(this, tr("Open File 1"),
		"",
		tr("Files (*.*)"));
	if (fileName1.isEmpty()) return;

	QString fileName2 = QFileDialog::getOpenFileName(this, tr("Open File 2"),
		"",
		tr("Files (*.*)"));
	if (fileName2.isEmpty()) return;

	QFile file1(fileName1);
	file1.open(QIODevice::ReadOnly);
	QByteArray buf1 = file1.readAll();
	file1.close();

	QFile file2(fileName2);
	file2.open(QIODevice::ReadOnly);
	QByteArray buf2 = file2.readAll();
	file2.close();

	int length = buf1.size() <= buf2.size() ? buf1.size() : buf2.size();
	int count = 0;
	long long diff = 0;
	long long total = 0;
	int neibor = 10;
	int width = 3264;
	int height = 2448;
	for (int i = 0; i < width - neibor; i++)
	{
		for (int j = 0; j < height - neibor; j++)
		{
			int v1 = 0;
			int v2 = 0;
			for (int m = i; m < i + neibor; m++)
			{
				for (int n = j; n < j + neibor; n++)
				{
					v1 += (unsigned char)buf1[n*width + m];
					v2 += (unsigned char)buf2[n*width + m];
				}
			}
			v1 /= neibor*neibor;
			v2 /= neibor*neibor;

			char dd = abs(v1 - v2);
			if (dd > 10) count++;
			diff += dd;
			total += v1;
		}
	}

	QMessageBox msgBox;
	msgBox.setText(QString("Pixels=%1\nDiff Ratio=%2")
		.arg(count * 100 / (length - neibor)*(height - neibor))
		.arg(diff * 100 / total));
	msgBox.exec();
}
